package com.tcoiss.datafactory.service.impl;

import com.tcoiss.common.component.api.RemoteLogService;
import com.tcoiss.common.component.api.model.SchemeVO;
import com.tcoiss.common.core.domain.R;
import com.tcoiss.common.core.enums.ErroEnums;
import com.tcoiss.common.core.exception.CustomException;
import com.tcoiss.common.log.annotation.SchemeLog;
import com.tcoiss.common.log.enums.BusinessType;
import com.tcoiss.datafactory.domain.ExecuteScheme;
import com.tcoiss.datafactory.domain.ExecuteWork;
import com.tcoiss.datafactory.service.IExecuteSchemeService;
import com.tcoiss.datafactory.service.IExecuteWorkService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Component
public class AsyncExecuteService {
    @Autowired
    private IExecuteWorkService iExecuteWorkService;

    @Resource
    private RemoteLogService remoteLogService;

    @Autowired
    private IExecuteSchemeService iExecuteSchemeService;


    @SchemeLog(title = "执行方案" , businessType = BusinessType.EXECUTE_SCHEME)
    @Async
    public void execute(SchemeVO vo) {
        //查询执行方案
        ExecuteScheme executeScheme = new ExecuteScheme();
        if (StringUtils.isNotBlank(vo.getExecuteNumber())) {
            executeScheme.setExecuteNumber(vo.getExecuteNumber());
        }
        if (vo.getExecuteType() != null) {
            executeScheme.setExecuteType(vo.getExecuteType());
        }
        List<ExecuteScheme> schemes = iExecuteSchemeService.queryList(executeScheme);
        if (schemes == null || schemes.size() == 0) {
            throw new CustomException(ErroEnums.DATAERRO.getCode(),new Object[]{},ErroEnums.DATAERRO.getInfo() + "未查询到相应的执行方案");
        }
        if (schemes.size() > 1) {
            throw new CustomException(ErroEnums.DATAERRO.getCode(),new Object[]{},ErroEnums.DATAERRO.getInfo() + "存在多个执行方案");
        }
        ExecuteScheme scheme = schemes.get(0);
        //根据执行方案查询作业
        List<ExecuteWork> works = iExecuteWorkService.getWorksBySchemeId(scheme.getSchemeId());
        if (works == null || works.size() == 0) {
            throw new CustomException(ErroEnums.DATAERRO.getCode(),new Object[]{scheme},ErroEnums.DATAERRO.getInfo() + "方案: " + scheme.getSchemeName() + "下未查询到可执行的作业");
        }
        //获取上次方案执行成功的时间，以此为数据更新的起始时间
        R<Date> r = remoteLogService.getSchemeLogNewTime(scheme.getExecuteNumber());
        if(r.getCode()!=200){
            throw new CustomException(ErroEnums.APIERRO.getCode(), new Object[]{scheme.getSchemeName(),},ErroEnums.APIERRO.getInfo() + r.getMsg());
        }
        boolean bool = false;
        vo.setLastExecuteTime(r.getData());
        // todo 根据执行策略，执行作业 1.串行 2.并行 3.异步
        switch (scheme.getExecuteStrategy()) {
            case 1:
                for (ExecuteWork work : works) {
                    if(work.getWorkType()==2&&!bool){
                        break;
                    }
                    boolean flag = iExecuteWorkService.executeWork(work, vo);
                    //上一个作业执行
                    if(flag&&work.getWorkType()==1){
                        bool = flag;
                    }
                }
                break;
            default:
                break;
        }
    }
}
